package org.ddxz.liquibase.config;

import com.alibaba.druid.pool.DruidDataSource;
import liquibase.integration.spring.SpringLiquibase;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;

import javax.sql.DataSource;

/**
 * description
 *
 * @author 朱宗刚
 * @version 1.0.0
 * @date 2024/3/17
 */

@Configuration
@MapperScan(basePackages = "org.ddxz.liquibase.*.mapper.mysql.**", sqlSessionTemplateRef = "mysqlSessionTemplate")
public class MysqlDatabaseConfig {
    @Bean("mysqlDataSource")
    @ConfigurationProperties(prefix = "spring.datasource.mysql")
    DataSource dataSource() {
        DruidDataSource datasource = new DruidDataSource();
        return datasource;
    }

    @Bean(name = "mysqlSessionFactory")
    public SqlSessionFactory mysqlSqlSessionFactory(@Qualifier("mysqlDataSource") DataSource dataSource) throws Exception {
        SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
        sqlSessionFactoryBean.setDataSource(dataSource);
        // 设置sql配置文件路径
        ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
        Resource[] configResources = resolver.getResources("classpath*:config/mapper/*/mysql/*.xml");
        Resource[] rootResources = resolver.getResources("classpath*:mapper/*/mysql/*.xml");
        Resource[] classResources = resolver.getResources("classpath*:com/eversec/evernssa/**/mapper/mysql/*.xml");
        Resource[] resources = new Resource[configResources.length + rootResources.length + classResources.length];
        int length = 0;
        if ((null != configResources && configResources.length > 0) && (null == rootResources || rootResources.length <= 0)) {
            System.arraycopy(configResources, 0, resources, 0, configResources.length);
            length = configResources.length;
        } else if ((null == configResources || configResources.length <= 0) && (null != rootResources && rootResources.length > 0)) {
            System.arraycopy(rootResources, 0, resources, 0, rootResources.length);
            length = rootResources.length;
        } else if ((null != configResources && configResources.length > 0) && (null != rootResources && rootResources.length > 0)) {
            System.arraycopy(configResources, 0, resources, 0, configResources.length);
            System.arraycopy(rootResources, 0, resources, configResources.length, rootResources.length);
            length = configResources.length + rootResources.length;
        }
        if (null != classResources && classResources.length > 0) {
            System.arraycopy(classResources, 0, resources, length, classResources.length);
        }
        sqlSessionFactoryBean.setMapperLocations(resources);
        return sqlSessionFactoryBean.getObject();
    }

    /**
     * 创建管理器
     *
     * @param dataSource
     * @return
     */

    @Bean(name = "mysqlTransactionManager")
    public DataSourceTransactionManager mysqlTranscationManager(@Qualifier("mysqlDataSource") DataSource dataSource) {
        return new DataSourceTransactionManager(dataSource);
    }

    /**
     * 创建模板
     *
     * @param sqlSessionFactory
     * @return
     * @throws Exception
     */

    @Bean(name = "mysqlSessionTemplate")
    public SqlSessionTemplate mysqlSqlSessionTemplate(@Qualifier("mysqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception {
        return new SqlSessionTemplate(sqlSessionFactory);
    }

    @Bean(name = "mysqlLiquibase")
    public SpringLiquibase liquibase(@Qualifier("mysqlDataSource") DataSource dataSource) {
        SpringLiquibase liquibase = new SpringLiquibase();
        liquibase.setDataSource(dataSource);
        liquibase.setChangeLog("classpath:liquibase/mysql/ddxz-mysql-sample.xml");
        liquibase.setDatabaseChangeLogTable("version_change_log");
        liquibase.setDatabaseChangeLogLockTable("version_change_lock");
        return liquibase;
    }
}
